<template>
  <div class="home-view">
    <nav>
      <div class="nav-left">
        <h1>光谷智慧交通</h1>
        <el-button @click="whatActually" :class="{ activate: isWhatActually }"
          >实时路况
        </el-button>
        <el-button
          v-if="user.type === 'user'"
          @click="examineNotice"
          :class="{ activate: dialogVisible }"
          >查看公告
        </el-button>
        <el-button
          v-if="user.type !== 'user'"
          :class="{ activate: isMonitorTrafficBtn }"
          @click="monitorTraffic"
          >查看监控
        </el-button>
        <el-button
          :class="{ activate: isEportTrafficBtn }"
          @click="reportTraffic"
          >{{ user.type === 'user' ? '报告路况' : '事件添加' }}</el-button
        >
        <el-button
          v-if="user.type !== 'user'"
          :class="{ activate: isEventQueryBtn }"
          @click="eventQuery"
          >事件查询
        </el-button>
        <el-button
          v-if="user.type !== 'user'"
          :class="{ activate: isEventUpdateBtn }"
          @click="eventUpdate"
          >事件更新
        </el-button>
        <el-button
          v-if="user.type !== 'user'"
          :class="{ activate: publishNoticeBtn }"
          @click="publishNotice"
          >发布公告
        </el-button>
        <el-button
          v-if="user.type !== 'user'"
          :class="{ activate: roadConditionBtn }"
          @click="roadConditionClick"
          >路况信息
        </el-button>
        <el-dropdown>
          <span class="el-dropdown-link">
            工具箱
            <el-icon class="el-icon--right">
              <arrow-down />
            </el-icon>
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="measureLength"
                >测量距离</el-dropdown-item
              >
              <el-dropdown-item @click="measureArea">测量面积</el-dropdown-item>
              <el-dropdown-item @click="clearMeasure"
                >清除测量</el-dropdown-item
              >
              <el-dropdown-item
                @click="closeMeasure"
                :disabled="brush == '' ? true : false"
                >关闭测量</el-dropdown-item
              >
              <el-dropdown-item @click="MapExportPng" divided
                >导出图片</el-dropdown-item
              >
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <el-button
          v-if="user.type === 'admin'"
          @click="userManagement"
          :class="{ activate: isUserManagementBtn }"
        >
          用户管理
        </el-button>
      </div>
      <div class="nav-right">
        <el-select
          v-model="searchText"
          placeholder="请选择交通事故类型"
          :prefix-icon="Search"
          @change="searchrRoadCondition"
        >
          <el-option label="碰撞" value="碰撞"></el-option>
          <el-option label="刮擦" value="刮擦"></el-option>
          <el-option label="碾压" value="碾压"></el-option>
          <el-option label="翻车" value="翻车"></el-option>
          <el-option label="失火" value="失火"></el-option>
          <el-option label="其他" value="其他"></el-option>
        </el-select>
        <el-button @click="openUserDrawer">
          <div class="user-info">
            <div class="head-portrait">
              <img :src="user.url" />
            </div>
            <div class="user-name">{{ user.username }}</div>
          </div>
        </el-button>
      </div>
    </nav>
    <div id="map"></div>
    <!-- 遮罩层 -->
    <!-- 这是工具箱的遮罩层 -->
    <div class="overlay"></div>
    <!-- 这是产看监控的遮罩层 -->
    <div class="monitoroverlay"></div>
    <!-- 这是事件更新的遮罩层 -->
    <div class="eventoverlay"></div>
    <!-- 这是产看公告的对话框 -->
    <el-dialog
      v-model="dialogVisible"
      title="查看公告"
      width="300"
      :close-on-click-modal="false"
    >
      <div v-for="(item, index) in notice">
        <span>公告{{ index + 1 }}：</span>
        <div style="margin: 10px 20px">时间：{{ item.time }}</div>
        <div style="margin: 0 20px">内容：{{ item.content }}</div>
        <el-divider v-if="index !== notice.length - 1" border-style="double" />
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 这是报告路况的对话框 -->
    <el-dialog
      v-model="reportTrafficVisible"
      title="报告路况"
      width="500"
      :close-on-click-modal="false"
      destroy-on-close
    >
      <RepoetEvent
        :coordinates="coordinates"
        @close-form="closeForm"
        v-if="user.type === 'user'"
      />
      <AddingEvent
        :docLayer="docLayer"
        :coordinates="coordinates"
        @close-form="closeForm"
        v-else
      />
    </el-dialog>
    <!-- 这是事件查询的对话框 -->
    <el-dialog
      class="event-card"
      width="800"
      v-model="eventCardVisible"
      draggable
      overflow
      :close-on-click-modal="false"
      :modal="false"
      destroy-on-close
      @close="clearHeatMap"
      :modal-class="'transparent-modal'"
    >
      <EventCard :insideCircle="insideCircle" @change-heat-map="isHeatMap" />
    </el-dialog>
    <!-- 这是发布公告弹窗 -->
    <el-dialog
      v-model="publishNoticeVisible"
      title="发布公告"
      width="300"
      header-class="publish-notice-header"
      :close-on-click-modal="false"
      destroy-on-close
      @close="publishNoticeClose"
    >
      <PublishNotice :selectInfo="selectInfo" @cancel="publishNoticeClose" />
    </el-dialog>
    <!-- 这是路况信息对话框 -->
    <el-dialog
      v-model="roadConditionVisible"
      title="路况信息"
      header-class="road-condition-header"
      width="600"
      :close-on-click-modal="false"
      destroy-on-close
      @close="clearRoadCondition"
    >
      <RoadCondition :coordinates="coordinates" />
    </el-dialog>
    <!-- 这是用户信息管理弹窗 -->
    <el-drawer v-model="userInfoDrawer" title="用户信息面板">
      <UserInfoDrawer />
    </el-drawer>
    <!-- 用户管理弹窗 -->
    <el-dialog
      v-model="userManagementVisible"
      title="用户管理"
      width="730"
      :close-on-click-modal="false"
      destroy-on-close
      @close="userManagementClose"
    >
      <UserManagement />
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { Search, ArrowDown } from '@element-plus/icons-vue';
import { userData } from '../stores/userData.js';
import { storeToRefs } from 'pinia';
import { getUserInfo, getNoticeList } from '../apis/index.js';
import { ElMessage } from 'element-plus';
import * as turf from '@turf/turf';

const router = useRouter();
const { user, localhostUrl } = storeToRefs(userData());
const map = ref(null);

let docLayer = ref(null);
//加载mapgis地图文档
docLayer.value = new Zondy.Map.Doc('', localhostUrl.value.map, {
  ip: localhostUrl.value.ip,
  port: localhostUrl.value.port,
  crossOrigin: 'anonymous',
});

//==================================实现显示实时路况================================================
// 在 setup 中声明响应式变量
const drawLayer = new ol.layer.Vector();
const isWhatActually = ref(false);

//查询所有信息
function queryAllData(querySuccess, queryError, id) {
  //初始化查询结构对象，设置查询结构包含几何信息
  var queryStruct = new Zondy.Service.QueryFeatureStruct();
  //是否包含几何图形信息
  queryStruct.IncludeGeometry = true;
  //是否包含属性信息
  queryStruct.IncludeAttribute = true;
  //是否包含图形显示参数
  queryStruct.IncludeWebGraphic = false;
  //实例化查询参数对象
  var queryParam = new Zondy.Service.QueryParameter({
    resultFormat: 'json',
    struct: queryStruct,
  });
  //设置查询分页号
  queryParam.pageIndex = 0;
  //设置查询要素数目
  queryParam.recordNumber = 100;
  var queryService = new Zondy.Service.QueryDocFeature(
    queryParam,
    localhostUrl.value.map,
    id,
    {
      ip: localhostUrl.value.ip,
      port: localhostUrl.value.port,
    }
  );
  //执行查询操作，querySuccess为查询回调函数
  queryService.query(querySuccess, queryError);
}

function whatActually() {
  if (isWhatActually.value) {
    isWhatActually.value = false;
    drawLayer.setVisible(false);
    return;
  } else {
    drawLayer.setVisible(true);
  }
  isWhatActually.value = true;
  queryAllData(querySuccess, queryError, 0);
}

//查询失败回调
function queryError(e) {
  ElMessage.warning('信息加载失败');
}

//查询成功回调
function querySuccess(result) {
  //初始化Zondy.Format.PolygonJSON类
  var format = new Zondy.Format.PolygonJSON();
  //将MapGIS要素JSON反序列化为ol.Feature类型数组
  var features = format.read(result);
  //实例化一个矢量图层drawLayerr用于高亮显示结果
  var drawSource = new ol.source.Vector({
    wrapX: false,
  });
  drawSource.addFeatures(features);
  drawLayer.setSource(drawSource);
  drawLayer.setStyle(clusterStyle);
}

function clusterStyle(feature) {
  const attributes = feature.getProperties().values_;
  let style = null;
  if (attributes.车流量 <= 1000) {
    style = new ol.style.Style({
      stroke: new ol.style.Stroke({
        color: 'rgba(0,255, 0, 1)',
        width: 5,
      }),
    });
  } else if (attributes.车流量 <= 1500) {
    style = new ol.style.Style({
      stroke: new ol.style.Stroke({
        color: 'rgba(255,255, 0, 1)',
        width: 5,
      }),
    });
  } else {
    style = new ol.style.Style({
      stroke: new ol.style.Stroke({
        color: 'rgba(255,0, 0, 1)',
        width: 5,
      }),
    });
  }
  return style;
}

//===============================查看公告===============================
const dialogVisible = ref(false);
const notice = ref([]);
const examineNotice = () => {
  dialogVisible.value = true;
  getNoticeList()
    .then((res) => {
      if (res.data.status === 1) {
        //先反转。然后获取前三条
        let data = res.data.content.reverse();
        let newData = data.slice(0, 3);
        notice.value = newData;
      } else {
        ElMessage.error('获取公告失败');
      }
    })
    .catch((err) => {
      ElMessage.error('获取公告失败');
    });
};

//===============================报告路况=================================
const isEportTrafficBtn = ref(false);
const reportTrafficVisible = ref(false);

//导入组件
import AddingEvent from '@/components/AddingEvent.vue';
import RepoetEvent from '@/components/RepoetEvent.vue';

let coordinates = ref();

let mapClick = (e) => {
  let coord = e.coordinate;
  coordinates.value = coord;
  queryIsByPosition(coord, isInRoad, 0);
};
const reportTraffic = () => {
  ManagementButton(6);
  isEportTrafficBtn.value = !isEportTrafficBtn.value;
  if (isEportTrafficBtn.value) {
    ElMessage('点击地图开始报告路况');
    map.value.on('click', mapClick);
  } else {
    map.value.un('click', mapClick);
  }
};

function queryIsByPosition(position, callback, id) {
  let pointObj = new Zondy.Object.Point2D(position[0], position[1]);
  pointObj.nearDis = 0.001; //可以添加一个模糊半径
  var queryStruct = new Zondy.Service.QueryFeatureStruct();
  //是否包含几何图形信息
  queryStruct.IncludeGeometry = true;
  //是否包含属性信息
  queryStruct.IncludeAttribute = true;
  //是否包含图形显示参数
  queryStruct.IncludeWebGraphic = false;
  //指定查询规则
  var rule = new Zondy.Service.QueryFeatureRule({
    //是否将要素的可见性计算在内
    EnableDisplayCondition: false,
    //是否完全包含
    MustInside: false,
    //是否仅比较要素的外包矩形
    CompareRectOnly: false,
    //是否相交
    Intersect: true,
  });
  //实例化查询参数对象
  var queryParam = new Zondy.Service.QueryParameter({
    r: Math.random(),
    geometry: pointObj,
    resultFormat: 'json',
    struct: queryStruct,
    rule: rule,
  });
  // //表示从第一页开始 查询20个
  // queryParam.pageIndex = 0;
  // // //设置查询要素数目
  // queryParam.recordNumber = 20;
  var queryService = new Zondy.Service.QueryDocFeature(
    queryParam,
    localhostUrl.value.map,
    id,
    {
      ip: localhostUrl.value.ip,
      port: localhostUrl.value.port,
    }
  );
  //执行查询操作，querySuccess为查询回调函数
  queryService.query(callback);
}

const isInRoad = (result) => {
  // console.log(result.SFEleArray, '查询结果');
  if (result.SFEleArray.length > 0) {
    //弹出对话框
    reportTrafficVisible.value = true;
  } else {
    ElMessage.warning('请在道路上报告事件');
  }
};

const closeForm = () => {
  //关闭对话框
  reportTrafficVisible.value = false;
  //关闭地图点击
  map.value.un('click', mapClick);
  //关闭按钮选中状态
  isEportTrafficBtn.value = false;
};

//===============================工具箱功能==============================
const brush = ref('');

//map 还可以添加覆盖物(overlay) overlay本质上就是一个dom 但是这个Dom可以和ol进行关联
let overlay = new ol.Overlay({
  positioning: 'top-center',
  offset: [0, 20],
});

let brushLayer = new ol.layer.Vector({
  source: new ol.source.Vector(),
  style: new ol.style.Style({
    stroke: new ol.style.Stroke({
      color: 'red',
      width: 2,
    }),
    fill: new ol.style.Fill({
      color: 'pink',
    }),
  }),
});

let draw = null;
const initDraw = () => {
  if (draw) {
    map.value.removeInteraction(draw);
    draw = null;
    map.value.getInteractions().forEach((interaction) => {
      if (interaction instanceof ol.interaction.Draw) {
        map.value.removeInteraction(interaction);
      }
    });
  }
  if (brush.value === 'length') {
    draw = new ol.interaction.Draw({
      type: 'LineString',
      source: brushLayer.getSource(),
    });
    map.value.addInteraction(draw);
  } else if (brush.value === 'area') {
    draw = new ol.interaction.Draw({
      type: 'Polygon',
      source: brushLayer.getSource(),
    });
    map.value.addInteraction(draw);
  } else {
    map.value.removeInteraction(draw);
    draw = null;
    // console.log('draw', brush.value, draw);
    map.value.getInteractions().forEach((interaction) => {
      if (interaction instanceof ol.interaction.Draw) {
        map.value.removeInteraction(interaction);
      }
    });
  }
  if (draw || brush.value) {
    //绑定新的事件
    draw.on('drawstart', (e) => {
      let f = e.feature;
      let g = f.getGeometry();
      g.on('change', (e) => {
        let g = e.target;
        if (brush.value === 'area') {
          draw.on('drawend', () => {
            let c = g.getCoordinates();
            let area = turf.area(turf.polygon(c), { units: 'kilometers' });
            var centroid = turf.centroid(turf.polygon(c));
            let element = overlay.getElement();
            element.innerHTML = '当前的面积为：' + area.toFixed(2) + 'km²';
            overlay.setPosition(centroid.geometry.coordinates);
          });
        } else if (brush.value === 'length') {
          let c = g.getCoordinates();
          let length = turf.length(turf.lineString(c), { units: 'kilometers' });
          let position = c[c.length - 1];
          let element = overlay.getElement();
          element.innerHTML = '当前的长度为：' + length.toFixed(2) + 'km';
          overlay.setPosition(position);
        } else {
          overlay.setPosition(undefined);
        }
      });
    });
  }
};

//测量长度
const measureLength = () => {
  ManagementButton(5);
  brush.value = 'length';
  initDraw();
};

//测量面积
const measureArea = () => {
  ManagementButton(5);
  brush.value = 'area';
  initDraw();
};

// 清除绘制
const clearMeasure = () => {
  brush.value = '';
  overlay.setPosition(undefined);
  brushLayer.getSource().clear(); // 清除所有绘制的内容
  initDraw();
};

// 关闭画笔
const closeMeasure = () => {
  brush.value = '';
  initDraw();
};

//导出地图
const MapExportPng = () => {
  //获取地图canvas
  const mapCanvas = map.value.getViewport().querySelector('canvas');
  var urlSa = mapCanvas.toDataURL();
  // 创建一个img标签，保存图片
  var newImg = document.createElement('img');
  newImg.src = urlSa;
  //利用a标签下载图片
  const a = document.createElement('a');
  a.href = urlSa;
  a.download = '地图.png';
  a.click();
};

//=====================================查看监控=================================
const isMonitorTrafficBtn = ref(false);
let monitoroverlay = new ol.Overlay({
  // element: document.getElementById('monitoroverlay'),
  offset: [-110, -210],
  autoPan: true,
});
const monitorClick = (e) => {
  let coord = e.coordinate;
  queryIsByPosition(coord, monitorSuccess, 2);
};

const monitorTraffic = () => {
  ManagementButton(4);
  isMonitorTrafficBtn.value = !isMonitorTrafficBtn.value;
  if (isMonitorTrafficBtn.value) {
    ElMessage('点击地图开始监控');
    map.value.on('click', monitorClick);
  } else {
    map.value.un('click', monitorClick);
    monitoroverlay.setPosition(undefined);
  }
};

//查询成功的回调
const monitorSuccess = (result) => {
  if (result.SFEleArray.length == 0) {
    return;
  }
  // 获取属性信息
  const attValues = result.SFEleArray[0].AttValue;

  const infoContent = attValues[2] || '无监控信息';
  const infoTitle = attValues[1] || '监控信息';

  let element = monitoroverlay.getElement();
  element.innerHTML = `
    <div class="content">
      <div class="title">摄像头编号：${infoTitle}</div>
      <p class="location">地点：${infoContent}</p>
      <video
        src="/4eca84b5b4b44cdf967e74b667697067.mp4"
        autoplay
        muted /* 添加静音属性保证自动播放 */
        controls /* 添加控制条 */
      ></video>
    </div>`;
  // 设置覆盖层位置
  const coordinate = [
    result.SFEleArray[0].fGeom.PntGeom[0].Dot.x,
    // 纵坐标等于纵坐标减去170px
    result.SFEleArray[0].fGeom.PntGeom[0].Dot.y,
  ];
  // console.log(coordinate);
  monitoroverlay.setPosition(coordinate);
};

//===============================事件查询===============================
const isEventQueryBtn = ref(false);
const eventCardVisible = ref(false);
import EventCard from '@/components/EventCard.vue';
let circleDraw = null;

const eventQuery = () => {
  ManagementButton(3);
  isEventQueryBtn.value = !isEventQueryBtn.value;
  if (isEventQueryBtn.value) {
    queryAllData(eventQuerySuccess, queryError, 3);
  } else {
    //关闭画笔
    circleDraw.setActive(false);
  }
};

let heatLayer = null;

let allEventList = [];
let insideCircle = ref([]);
const eventQuerySuccess = (result) => {
  //初始化Zondy.Format.PolygonJSON类
  var format = new Zondy.Format.PolygonJSON();
  //将MapGIS要素JSON反序列化为ol.Feature类型数组
  var features = format.read(result);
  allEventList = features;
  //创建一个画笔，绘制圆形
  // clearCircleInteraction();
  circleDraw = new ol.interaction.Draw({
    type: 'Circle',
    //只能绘制一个
    maxPoints: 1,
  });
  map.value.addInteraction(circleDraw);
  //绑定圆形绘制事件
  circleDraw.on('drawend', (e) => {
    let f = e.feature;
    let g = f.getGeometry();
    //查询在圆形内的事件点
    let c = g.getCenter(); //圆心坐标
    let radius = g.getRadius() * 100;
    //在圆上的点
    insideCircle.value = allEventList.filter((item) => {
      let coord = item.getGeometry().getCoordinates();
      if (coord.length == 1) {
        coord = coord[0];
      }
      let distance = turf.distance(turf.point(c), turf.point(coord), {
        units: 'kilometers',
      });
      return distance <= radius;
    });
    //打开对话框
    eventCardVisible.value = true;
    //关闭圆形绘制
    circleDraw.setActive(false);
    //关闭事件查询按钮
    isEventQueryBtn.value = false;
  });
};

// 清除热力图
const clearHeatMap = () => {
  if (heatLayer) {
    map.value.removeLayer(heatLayer);
    heatLayer.getSource().clear(); // 新增清除数据源操作
    heatLayer = null;
  }
};

// 显示热力图
const isHeatMap = (is = false, radius, size) => {
  if (is) {
    // 清理旧的热力图图层（防止重复）
    const layers = map.value.getLayers().getArray();
    for (let i = layers.length - 1; i >= 0; i--) {
      if (layers[i] instanceof ol.layer.Heatmap) {
        map.value.removeLayer(layers[i]);
      }
    }

    // 创建新的热力图
    heatLayer = new ol.layer.Heatmap({
      source: new ol.source.Vector({ features: allEventList }),
    });
    map.value.addLayer(heatLayer);
    heatLayer.setRadius(radius);
    heatLayer.setBlur(size);
    heatLayer.setVisible(true);
  } else {
    clearHeatMap(); // 复用清除函数
  }
};

//===============================事件更新==============================
const isEventUpdateBtn = ref(false);

//创建遮罩层
let eventoverlay = new ol.Overlay({
  // element: document.getElementById('eventoverlay'),
  autoPan: true,
});

//地图点击事件
const eventUpdateClick = (e) => {
  let coord = e.coordinate;
  queryIsByPosition(coord, eventUpdateSuccess, 3);
};

//事件更新按钮点击事件
const eventUpdate = () => {
  ManagementButton(2);
  isEventUpdateBtn.value = !isEventUpdateBtn.value;
  if (isEventUpdateBtn.value) {
    ElMessage('点击事件位置，开始更新事件');
    map.value.on('click', eventUpdateClick);
  } else {
    map.value.un('click', eventUpdateClick);
    eventoverlay.setPosition(undefined);
  }
};

//查询成功的回调
const eventUpdateSuccess = (result) => {
  //初始化Zondy.Format.PolygonJSON类
  var format = new Zondy.Format.PolygonJSON();
  //将MapGIS要素JSON反序列化为ol.Feature类型数组
  var features = format.read(result);
  let value = null;
  let fid = null;
  if (features) {
    //获取属性信息
    value = features[0].getProperties().values_;
    fid = features[0].getId();
  } else {
    return;
  }
  let element = eventoverlay.getElement();
  element.innerHTML = `
    <div class="header">
      <div class="title">事件详细信息</div>
      <div class="close" @click="closeEventUpdate" id="closeEventBtn">×</div>
    </div>
    <div class="content">
      <p>事件编号：${value.事件编号}</p>
      <p>事件类型：${value.事件类型}</p>
      <p>事件等级：${value.事件等级}</p>
      <p>发生时间：${value.发生时间}</p>
      <p>发生地点：${value.发生地点}</p>
      <p>车牌号：${value.车牌号}</p>
      <p>驾驶员：${value.驾驶员}</p>
      <div>
        <span>处理状态：</span>
        <select class="EventStatus">
          <option label="未处理" value="0"></option>
          <option label="处理中" value="1"></option>
          <option label="已处理" value="2"></option>
        </select>
      </div>
      <div>
        <button id="updateEventBtn" style="background-color: #4CAF50; color: white;">更新</button>
        <button id="cancelEventBtn" style="background-color: #f44336; color: white;">取消</button>
      </div>
    </div>`;
  // 设置覆盖层位置
  const coordinate = [
    result.SFEleArray[0].fGeom.PntGeom[0].Dot.x,
    result.SFEleArray[0].fGeom.PntGeom[0].Dot.y,
  ];
  eventoverlay.setPosition(coordinate);
  //获取eventoverlay的高度
  const height = eventoverlay.getElement().offsetHeight;
  //动态设置覆盖层偏移
  eventoverlay.setOffset([-100, -height - 12]);
  //给选择器赋值
  document.querySelector('.EventStatus').value = value.处理状态;
  // 添加事件监听，这里需要手动添加
  document.getElementById('closeEventBtn').addEventListener('click', () => {
    closeEventUpdate();
  });
  document.getElementById('updateEventBtn').addEventListener('click', () => {
    updateEvent(fid, 3, value.处理状态);
  });
  document.getElementById('cancelEventBtn').addEventListener('click', () => {
    closeEventUpdate();
  });
};

//取消更新事件
const closeEventUpdate = () => {
  eventoverlay.setPosition(undefined);
  //关闭按钮
  isEventUpdateBtn.value = false;
  //移除地图点击事件
  map.value.un('click', eventUpdateClick);
};

//更新事件
const updateEvent = (fid, layerIndex, status) => {
  //获取处理状态
  const newStatus = document.querySelector('.EventStatus').value;
  //更新事件的逻辑
  if (status === newStatus) {
    return;
  }
  let color = '';
  if (newStatus === '0') {
    color = '6';
  } else if (newStatus === '1') {
    color = '4';
  } else {
    color = '90';
  }
  //更新属性
  const AttValue = [newStatus];
  //更新样式信息
  const pointInfo = new Zondy.Object.CPointInfo({
    //子图角度，取值范围为0~360。
    Angle: 0,
    //子图颜色（请参考MapGIS颜色库中颜色编号）
    Color: color,
    //子图高度
    SymHeight: 5,
    //子图ID（请参考MapGIS符号库中线符号编号）
    SymID: 21,
    //子图宽度
    SymWidth: 5,
  });
  //设置当前要素的图形参数信息
  const webGraphicInfo = new Zondy.Object.WebGraphicsInfo({
    InfoType: 1, //1=>point 2=>line 3=>aarea
    PntInfo: pointInfo,
  });
  const newFeature = new Zondy.Object.Feature({
    //更新的时候 Attvalue 必须更新(可以传之前相同的值) 其他2个配置 可以不更新
    AttValue,
    GraphicInfo: webGraphicInfo,
  });
  newFeature.setFType(1);
  //将新增要素的id设置为需要修改的那个要素的id
  newFeature.setFID(fid);
  /* 2、创建要素集映射 */
  //创建一个点要素数据集
  const featureSet = new Zondy.Object.FeatureSet();
  //设置属性结构
  const cAttStruct = new Zondy.Object.CAttStruct({
    FldName: ['处理状态'],
    FldNumber: 1,
    FldType: ['short'],
  });
  featureSet.AttStruct = cAttStruct;
  //添加要素到要素数据集
  featureSet.addFeature(newFeature);
  /* 3、调用服务执行更新 */
  const editService = new Zondy.Service.EditDocFeature(
    localhostUrl.value.map,
    layerIndex,
    {
      ip: localhostUrl.value.ip,
      port: localhostUrl.value.port,
    }
  );
  editService.update(featureSet, (data) => {
    onPointSuccess(data, docLayer.value);
  });
};

//更新成功回调
function onPointSuccess(data, layer) {
  if (data.succeed) {
    ElMessage.success('更新成功');
    layer.refresh();
    closeEventUpdate();
  } else {
    ElMessage.error('更新失败');
  }
}
//===============================发布公告===============================
//发布公告弹框
const publishNoticeVisible = ref(false);
//发布公告按钮
const publishNoticeBtn = ref(false);
//导入公告弹窗组件
import PublishNotice from '@/components/PublishNotice.vue';
//多边形画笔
let polygonDraw = null;
//选中的居民区要素
let selectFeature = null;
//选中的居民区信息
let selectInfo = ref([]);
//画笔绘画结束时的回调
let polygonDrawEnd = (e) => {
  let f = e.feature;
  let g = f.getGeometry();
  GeomQuery(g, 4, publishNoticeSuccess, queryError);
};
const publishNotice = () => {
  ManagementButton(1);
  publishNoticeBtn.value = !publishNoticeBtn.value;
  if (publishNoticeBtn.value) {
    polygonDraw = new ol.interaction.Draw({
      type: 'Polygon',
      source: new ol.source.Vector(),
    });
    map.value.addInteraction(polygonDraw);
    polygonDraw.on('drawend', polygonDrawEnd);
  } else {
    polygonDraw.setActive(false);
    map.value.removeInteraction(polygonDraw);
    polygonDraw = null;
  }
};

const GeomQuery = (geomZD, id, querySuccess, queryError) => {
  //初始化查询结构对象，设置查询结构包含几何信息
  var queryStruct = new Zondy.Service.QueryFeatureStruct();
  //是否包含几何图形信息
  queryStruct.IncludeGeometry = true;
  //是否包含属性信息
  queryStruct.IncludeAttribute = true;
  //是否包含图形显示参数
  queryStruct.IncludeWebGraphic = false;
  //指定查询规则
  var rule = new Zondy.Service.QueryFeatureRule({
    //是否将要素的可见性计算在内
    EnableDisplayCondition: false,
    //是否完全包含
    MustInside: false,
    //是否仅比较要素的外包矩形
    CompareRectOnly: false,
    //是否相交
    Intersect: true,
  });
  //实例化查询参数对象 参数中的g是ol的几何体 最终要将它转为MAPGIS的几何体
  const geomObj = new Zondy.Object.Polygon();
  geomObj.setByOL(geomZD); //可以将OL中的几何体转为MAPGIS中的几何体
  var queryParam = new Zondy.Service.QueryParameter({
    geometry: geomObj,
    resultFormat: 'json',
    struct: queryStruct,
    rule: rule,
  });
  //设置查询分页号
  queryParam.pageIndex = 0;
  //设置查询要素数目
  queryParam.recordNumber = 99;
  var queryService = new Zondy.Service.QueryDocFeature(
    queryParam,
    localhostUrl.value.map,
    id,
    {
      ip: localhostUrl.value.ip,
      port: localhostUrl.value.port,
    }
  );
  //执行查询操作，querySuccess为查询回调函数
  queryService.query(querySuccess, queryError);
};

//发布公告弹窗关闭时的回调
const publishNoticeClose = () => {
  //清除选中的居民区要素
  if (selectFeature) {
    selectFeature.getSource().clear(); // 清除旧的要素
    map.value.removeLayer(selectFeature);
    selectFeature = null;
  }
  //清除选中的居民区信息
  selectInfo.value = [];
  //关闭弹窗
  publishNoticeVisible.value = false;
  //关闭发布公告按钮
  publishNoticeBtn.value = false;
};

//查询成功回调
const publishNoticeSuccess = (result) => {
  //初始化Zondy.Format.PolygonJSON类
  var format = new Zondy.Format.PolygonJSON();
  //将MapGIS要素JSON反序列化为ol.Feature类型数组
  var features = format.read(result);
  if (features) {
    //创建一个图层将这些数据显示到。
    features.forEach((item) => {
      const properties = item.getProperties().values_;
      selectInfo.value.push(properties);
    });
    if (selectFeature) {
      selectFeature.getSource().clear(); // 清除旧的要素
    }
    selectFeature = new ol.layer.Vector({
      source: new ol.source.Vector({
        features: features,
      }),
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: '#fe6500',
          width: 1,
        }),
        fill: new ol.style.Fill({
          color: '#8da6ff',
        }),
      }),
    });
    //将图层添加到地图上
    map.value.addLayer(selectFeature);
    //关闭画笔
    polygonDraw.setActive(false);
    //打开弹窗
    publishNoticeVisible.value = true;
  } else {
    if (selectFeature) {
      selectFeature.getSource().clear(); // 清除旧的要素
    }
    ElMessage.warning('没有找到相关居民区');
  }
};

//===============================路况信息================================
const roadConditionVisible = ref(false);
const roadConditionBtn = ref(false);
import RoadCondition from '@/components/RoadCondition.vue';

//路况信息点击事件
const roadConditionClick = () => {
  roadConditionVisible.value = !roadConditionVisible.value;
  roadConditionBtn.value = !roadConditionBtn.value;
};

//关闭
const clearRoadCondition = () => {
  roadConditionVisible.value = false;
  roadConditionBtn.value = false;
};

//===============================搜索功能================================
const searchText = ref('');
let eventLayer = null;
//筛选事件的方法
const filterEvent = (result) => {
  //初始化Zondy.Format.PolygonJSON类
  var format = new Zondy.Format.PolygonJSON();
  //将MapGIS要素JSON反序列化为ol.Feature类型数组
  var features = format.read(result);
  //拿到features里的信息
  let data = features.filter((item) => {
    return item.getProperties().values_.事件类型 === searchText.value;
  });
  if (eventLayer) {
    eventLayer.getSource().clear(); // 清除旧的要素
  }
  if (data.length > 0) {
    var eventSource = new ol.source.Vector({
      wrapX: false,
    });
    eventSource.addFeatures(data);
    //实例化一个矢量图层eventLayer用于显示结果，这是点要素，显示为图标
    eventLayer = new ol.layer.Vector({
      source: eventSource,
      style: new ol.style.Style({
        image: new ol.style.Icon({
          anchor: [0.5, 0.95],
          src: '../../public/dingwei.png',
          scale: 0.2,
        }),
      }),
    });
    //将eventLayer添加到地图上
    map.value.addLayer(eventLayer);
  } else {
    ElMessage.error('没有找到相关事件');
  }
};

const searchrRoadCondition = () => {
  //调用查找事件图层方法
  queryAllData(filterEvent, queryError, 3);
};

//===============================用户管理================================
const userManagementVisible = ref(false);
const isUserManagementBtn = ref(false);
import UserManagement from '@/components/UserManagement.vue';
//按钮点击事件
const userManagement = () => {
  userManagementVisible.value = !userManagementVisible.value;
  isUserManagementBtn.value = !isUserManagementBtn.value;
  //按钮点击事件
};

const userManagementClose = () => {
  userManagementVisible.value = false;
  isUserManagementBtn.value = false;
};

//===============================用户信息功能=============================
const userInfoDrawer = ref(false);
import UserInfoDrawer from '@/components/UserInfoDrawer.vue';

const openUserDrawer = () => {
  userInfoDrawer.value = true;
};

const residentStyle = (result) => {
  //初始化Zondy.Format.PolygonJSON类
  var format = new Zondy.Format.PolygonJSON();
  //将MapGIS要素JSON反序列化为ol.Feature类型数组
  var features = format.read(result);
  //拿到features里的信息
  features.forEach((item, index) => {
    const properties = item.getProperties().values_;
    const uname = properties.name;
    let fid = item.getId();
    //随机1-100的整数
    // const index = Math.floor(Math.random() * 100) + 1;
    updateresidentStyle(fid, 4, uname, 1620 - index);
  });
};

const updateresidentStyle = (fid, layerIndex, newdata, color) => {
  //获取处理状态
  //更新事件的逻辑
  //更新属性
  const AttValue = [newdata];
  //更新样式信息
  var cRegionInfo = new Zondy.Object.CRegionInfo({
    //结束填充颜色，在渐变模式下设置才有意义。（请参考MapGIS颜色库中颜色编号）
    EndColor: 0,
    //填充颜色，在渐变模式下设置才有意义。（请参考MapGIS颜色库中颜色编号）
    FillColor: 0,
    //填充模式。取值范围：0（常规模式）、1（线性渐变模式）、2（矩形渐变模式）、3（圆形渐变模式）。
    FillMode: 0,
    //填充图案笔宽
    OutPenWidth: 1,
    //填充图案角度，取值范围为0~360。
    PatAngle: 1,
    //填充图案颜色（请参考MapGIS颜色库中颜色编号）
    PatColor: color,
    //填充图案高度
    PatHeight: 1,
    //填充图案ID（请参考MapGIS符号库中线符号编号）
    PatID: 1,
    //填充图案宽度
    PatWidth: 1,
  });
  //设置当前要素的图形参数信息
  const webGraphicInfo = new Zondy.Object.WebGraphicsInfo({
    InfoType: 3, //1=>point 2=>line 3=>aarea
    RegInfo: cRegionInfo,
  });
  const newFeature = new Zondy.Object.Feature({
    //更新的时候 Attvalue 必须更新(可以传之前相同的值) 其他2个配置 可以不更新
    AttValue,
    GraphicInfo: webGraphicInfo,
  });
  newFeature.setFType(1);
  //将新增要素的id设置为需要修改的那个要素的id
  newFeature.setFID(fid);
  /* 2、创建要素集映射 */
  //创建一个点要素数据集
  const featureSet = new Zondy.Object.FeatureSet();
  //设置属性结构
  const cAttStruct = new Zondy.Object.CAttStruct({
    FldName: ['name'],
    FldNumber: 1,
    FldType: ['string'],
  });
  featureSet.AttStruct = cAttStruct;
  //添加要素到要素数据集
  featureSet.addFeature(newFeature);
  /* 3、调用服务执行更新 */
  const editService = new Zondy.Service.EditDocFeature(
    localhostUrl.value.map,
    layerIndex,
    {
      ip: localhostUrl.value.ip,
      port: localhostUrl.value.port,
    }
  );
  editService.update(featureSet, (data) => {
    onSuccess(data, docLayer.value);
  });
};

//更新成功回调
function onSuccess(data, layer) {
  if (data.succeed) {
    layer.refresh();
  }
}

//居民区样式，调用一次即可
// queryAllData(residentStyle, queryError, 4);

//管理按钮互斥功能
const ManagementButton = (id) => {
  //发布公告
  if (publishNoticeBtn.value && id != 1) {
    publishNoticeClose();
    polygonDraw.setActive(false);
  }
  //事件更新
  if (isEventUpdateBtn.value && id != 2) {
    closeEventUpdate();
  }
  //事件查询
  if (isEventQueryBtn.value && id != 3) {
    isEventQueryBtn.value = false;
    eventCardVisible.value = false;
    circleDraw.setActive(false);
  }
  //查看监控
  if (isMonitorTrafficBtn.value && id != 4) {
    isMonitorTrafficBtn.value = false;
    map.value.un('click', monitorClick);
    monitoroverlay.setPosition(undefined);
  }
  //测量工具
  if (draw && id != 5) {
    draw.setActive(false);
  }
  //报告路况
  if (isEportTrafficBtn.value && id != 6) {
    closeForm();
  }
};

onMounted(() => {
  map.value = new ol.Map({
    target: 'map',
    view: new ol.View({
      center: [114.37, 30.49],
      zoom: 13,
      projection: 'EPSG:4326',
    }),
    layers: [
      new ol.layer.Tile({
        source: new ol.source.XYZ({
          url: 'http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=b31da3e886902fbc3db6f0dd8b454b21',
          crossOrigin: 'anonymous',
        }),
      }),
    ],
  });
  map.value.addLayer(docLayer.value);
  map.value.addLayer(drawLayer);
  map.value.addLayer(brushLayer);

  //添加overlay
  overlay.setElement(document.querySelector('.overlay'));
  map.value.addOverlay(overlay);

  monitoroverlay.setElement(document.querySelector('.monitoroverlay'));
  map.value.addOverlay(monitoroverlay);

  eventoverlay.setElement(document.querySelector('.eventoverlay'));
  map.value.addOverlay(eventoverlay);

  overlay.setVisible(true);

  const token = localStorage.getItem('jwtToken');
  const userJson = JSON.parse(localStorage.getItem('user')) || {};
  // 监听路由变化，根据路由名称显示或隐藏对应的功能
  router.beforeEach((to, from, next) => {
    // 需要登录且无token → 跳转登录
    if (to.matched.some((record) => record.meta.requiresAuth)) {
      if (!token) {
        next('/login');
        return;
      }

      if (token) {
        const payload = JSON.parse(atob(token.split('.')[1]));
        const exp = payload.exp * 1000;
        if (Date.now() > exp) {
          localStorage.removeItem('jwtToken');
          next('/login');
          return;
        }
      }
    }
    next();
  });
  //登录时获取用户信息
  getUserInfo(userJson)
    .then((res) => {
      user.value = res.data.data;
    })
    .catch((err) => {
      ElMessage.error('获取用户信息失败');
    });
});
</script>

<style lang="scss" scoped>
.home-view {
  width: 100vw;
  height: 100vh;
  nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    height: 60px;
    .nav-left {
      display: flex;
      align-items: center;
      h1 {
        font-size: 24px;
        // width: 150px;
        margin: 0 10px;
      }
      .el-button {
        padding: 10px 15px;
        height: 40px;
        border-radius: 0;
        border: none;
        box-shadow: none;
        outline: none;
        margin: 0;
        line-height: 20px;
      }
      .el-button.activate {
        background-color: rgb(235.9, 245.3, 255);
        color: #409eff;
      }
      .el-dropdown {
        padding: 10px 15px;
        height: 40px;
        line-height: 20px;
        border: none;
        box-shadow: none;
        cursor: pointer;
        .el-icon {
          line-height: 40px;
          transition: all 0.3s;
        }
      }
      .el-dropdown:hover {
        color: #409eff;
      }
      .el-dropdown:hover .el-icon {
        transform: rotate(180deg);
      }
    }
    .nav-right {
      display: flex;
      align-items: center;
      .el-select {
        width: 250px;
        :deep(.el-select__wrapper) {
          border: 1px solid #c0c4cc;
          box-shadow: none;
        }
        .el-select__wrapper:hover {
          box-shadow: none;
        }
        .el-select__wrapper.is-focus {
          border: 1px solid #c0c4cc;
          box-shadow: none;
        }
      }
      .el-button {
        width: 150px;
        height: 60px;
        border: none;
        box-shadow: none;
        .user-info {
          display: flex;
          align-items: center;
          gap: 5px;
          // padding: 0 40px;
          cursor: pointer;
          .head-portrait {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-size: cover;
            img {
              width: 100%;
              height: 100%;
              border-radius: 50%;
              // 缩小取保合适
              object-fit: cover;
            }
          }
          .user-name {
            width: 70px;
            height: 30px;
            line-height: 30px;
            white-space: nowrap;
            text-overflow: ellipsis;
            overflow: hidden;
            font-size: 17px;
            color: #303133;
          }
        }
      }
      .el-button:hover {
        border: none;
        background-color: white;
      }
    }
  }
  #map {
    width: 100%;
    height: calc(100vh - 60px);
    // background-color: red;
  }
  .overlay {
    background-color: white;
    padding: 15px;
    border-radius: 5px;
    box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.3);
    p {
      line-height: 26px;
    }
  }
  .overlay::after {
    width: 20px;
    height: 20px;
    content: '';
    position: absolute;
    top: -5px;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
    background-color: white;
  }

  .monitoroverlay {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
    border-radius: 8px;
    background-color: white;
    padding: 15px 10px;
    z-index: 2;
    /* 内容区域样式 */
    :deep(.content) {
      display: flex;
      flex-direction: column;
      gap: 5px;
      .location {
        margin: 0;
        font-size: 12px;
        color: #333;
        font-weight: 500;
      }
      .title {
        margin: 0;
        font-size: 14px;
        color: rgb(14, 43, 100);
      }
      video {
        width: 200px;
        height: 120px;
        border-radius: 4px;
        object-fit: cover;
        /* 保持视频比例 */
        background: #000;
        z-index: 2;
      }
    }
  }

  .monitoroverlay::after {
    width: 20px;
    height: 20px;
    content: '';
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
    background-color: white;
    z-index: 1;
  }

  .eventoverlay {
    background-color: rgb(255, 255, 255);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
    font-size: 12px;
    width: 200px;
    :deep(.header) {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 2px 5px;
      background-color: #409eff;
      .title {
        font-size: 13px;
        color: white;
        font-weight: 500;
      }
      .close {
        cursor: pointer;
        font-size: 18px;
      }
      .close:hover {
        color: white;
      }
    }
    :deep(.content) {
      display: flex;
      flex-direction: column;
      gap: 5px;
      padding: 10px;
      div {
        display: flex;
        align-items: center;
        gap: 10px;
        select {
          font-size: 12px;
          padding: 2px 5px;
          border: 1px solid #c0c4cc;
          box-shadow: none;
          outline: none;
        }
        button {
          outline: none;
          border: none;
          font-size: 12px;
          padding: 2px 5px;
          margin: 5px auto;
        }
      }
    }
  }

  .eventoverlay::after {
    width: 20px;
    height: 20px;
    content: '';
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%) rotate(45deg);
    background-color: white;
    z-index: 1;
  }

  .event-card {
    z-index: 1000;
    width: 800px;
    background-color: #fff;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
  }
}
.el-dropdown-link {
  outline: none !important;
}

.el-dropdown-link:focus {
  outline: none !important;
}

.user-info-content {
  display: flex;
  flex-direction: column;
  button {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 10px;
    background-color: white;
    border: none;
    font-size: 16px;
    cursor: pointer;
    color: #444;
  }
  button:hover {
    background-color: rgb(235.9, 245.3, 255);
  }
}
</style>
